import jwt, { SignOptions } from 'jsonwebtoken';
import { Request, Response, NextFunction } from 'express';

// 暂时注释掉不存在的模块，稍后需要创建或修改
// import UserPrisma from '../models/UserPrisma';
// import Administrator from '../models/AdministratorPrisma';

/**
 * 用户接口定义
 */
interface User {
  id: string;
  username?: string;
  email?: string;
  status: 'active' | 'inactive' | 'pending';
  publishing_credits: number;
  [key: string]: any;
}

/**
 * 管理员接口定义
 */
interface Admin {
  id: string;
  username: string;
  [key: string]: any;
}

/**
 * JWT载荷接口
 */
interface JwtPayload {
  user_id?: string;
  admin_id?: string;
  [key: string]: any;
}

/**
 * 扩展Request接口以包含用户和管理员信息
 */
declare global {
  namespace Express {
    interface Request {
      user?: User;
      admin?: { id: string; username: string };
    }
  }
}

/**
 * JWT认证中间件
 * 验证请求头中的token，并将用户信息添加到req.user中
 */
export const authenticateToken = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
  try {
    // 从请求头获取token
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      res.status(401).json({
        success: false,
        message: '访问令牌缺失'
      });
      return;
    }

    // 验证token
    const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
    
    // TODO: 需要实现用户查询逻辑
    // 查询用户信息
    // const user = await UserPrisma.findById(decoded.user_id);
    // if (!user) {
    //   res.status(401).json({
    //     success: false,
    //     message: '用户不存在'
    //   });
    //   return;
    // }

    // // 将用户信息添加到请求对象中
    // req.user = user;
    
    // 暂时模拟用户信息
    req.user = {
      id: decoded.user_id as string,
      status: 'active',
      publishing_credits: 10
    } as User;
    
    next();
  } catch (error: any) {
    console.error('Token验证失败:', error.message);
    
    if (error.name === 'JsonWebTokenError') {
      res.status(401).json({
        success: false,
        message: '无效的访问令牌'
      });
      return;
    }
    
    if (error.name === 'TokenExpiredError') {
      res.status(401).json({
        success: false,
        message: '访问令牌已过期'
      });
      return;
    }
    
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
};

/**
 * 可选的JWT认证中间件
 * 如果有token则验证，没有token则继续执行
 */
export const optionalAuth = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (token) {
      const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
      
      // TODO: 需要实现用户查询逻辑
      // const user = await UserPrisma.findById(decoded.user_id);
      // if (user) {
      //   req.user = user;
      // }
      
      // 暂时模拟用户信息
      req.user = {
        id: decoded.user_id as string,
        status: 'active',
        publishing_credits: 10
      } as User;
    }
    
    next();
  } catch (error) {
    // 可选认证失败时不返回错误，继续执行
    next();
  }
};

/**
 * 检查用户是否已激活
 */
export const requireActive = (req: Request, res: Response, next: NextFunction): void => {
  if (!req.user) {
    res.status(401).json({
      success: false,
      message: '请先登录'
    });
    return;
  }

  if (req.user.status !== 'active') {
    res.status(403).json({
      success: false,
      message: '账户未激活，请先激活账户'
    });
    return;
  }

  next();
};

/**
 * 检查用户发布额度
 */
export const requireCredits = (req: Request, res: Response, next: NextFunction): void => {
  if (!req.user) {
    res.status(401).json({
      success: false,
      message: '请先登录'
    });
    return;
  }

  if (req.user.publishing_credits <= 0) {
    res.status(403).json({
      success: false,
      message: '发布额度不足，请购买套餐'
    });
    return;
  }

  next();
};

/**
 * 生成JWT token
 * @param payload 载荷数据
 * @param expiresIn 过期时间
 * @returns JWT token
 */
export const generateToken = (payload: object, expiresIn: string = process.env.JWT_EXPIRES_IN || '7d'): string => {
  const options: SignOptions = { expiresIn: expiresIn as any };
  return jwt.sign(payload, process.env.JWT_SECRET as string, options);
};

/**
 * 验证JWT token
 * @param token JWT token
 * @returns 解码后的载荷
 */
export const verifyToken = (token: string): JwtPayload => {
  return jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;
};

/**
 * 管理员JWT认证中间件
 * 验证请求头中的token，并将管理员信息添加到req.admin中
 */
export const authenticateAdmin = async (req: Request, res: Response, next: NextFunction): Promise<void> => {
  try {
    // 从请求头获取token
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      res.status(401).json({
        success: false,
        message: '访问令牌缺失'
      });
      return;
    }

    // 验证token
    const decoded = jwt.verify(token, process.env.JWT_SECRET as string) as JwtPayload;

    // 检查是否为管理员token
    if (!decoded.admin_id) {
      res.status(401).json({
        success: false,
        message: '无效的管理员令牌'
      });
      return;
    }

    // TODO: 需要实现管理员查询逻辑
    // 查找管理员
    // const admin = await Administrator.findById(decoded.admin_id);
    // if (!admin) {
    //   res.status(401).json({
    //     success: false,
    //     message: '管理员不存在'
    //   });
    //   return;
    // }

    // 将管理员信息添加到请求对象中
    req.admin = {
      id: decoded.admin_id,
      username: 'admin' // 暂时硬编码，稍后从数据库获取
    };

    next();
  } catch (error: any) {
    console.error('管理员Token验证失败:', error.message);
    res.status(401).json({
      success: false,
      message: '无效的访问令牌'
    });
  }
};

/**
 * 生成管理员JWT token
 * @param admin 管理员信息
 * @returns JWT token
 */
export const generateAdminToken = (admin: Admin): string => {
  const payload = {
    admin_id: admin.id,
    username: admin.username
  };

  const options: SignOptions = {
    expiresIn: (process.env.JWT_EXPIRES_IN || '7d') as any
  };
  return jwt.sign(payload, process.env.JWT_SECRET as string, options);
};